package com.pureut.equipment.service.impl;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pureut.common.core.exception.GlobalException;
import com.pureut.common.core.web.domain.AjaxResult;
import com.pureut.common.datascope.annotation.DataScope;
import com.pureut.common.security.utils.DictUtils;
import com.pureut.common.security.utils.SecurityUtils;
import com.pureut.equipment.domain.PatrolItem;
import com.pureut.equipment.domain.PatrolWorkOrder;
import com.pureut.equipment.domain.PatrolWorkOrderProject;
import com.pureut.equipment.domain.dto.*;
import com.pureut.equipment.domain.vo.AuditVo;
import com.pureut.equipment.domain.vo.PatrolWorkOrderProjectVo;
import com.pureut.equipment.domain.vo.PatrolWorkOrderVo;
import com.pureut.equipment.mapper.PatrolItemMapper;
import com.pureut.equipment.mapper.PatrolWorkOrderMapper;
import com.pureut.equipment.mapper.PatrolWorkOrderProjectMapper;
import com.pureut.equipment.service.PatrolWorkOrderProjectService;
import com.pureut.equipment.service.PatrolWorkOrderService;
import com.pureut.equipment.util.TimeUtils;
import com.pureut.production.api.FeignProductionService;
import com.pureut.system.api.FeignService;
import com.pureut.system.api.domain.SysDictData;
import com.pureut.system.api.domain.SysUser;
import com.pureut.system.api.vo.SysAuditHistoryVo;
import com.pureut.system.api.vo.SysWorkbenchAuditAgentVo;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/***
 *
 * Author:巡检工单实现层
 * Date:2023/04/26 13:45
 * @DESC
 */
@Service
public class PatrolWorkOrderServiceImpl extends ServiceImpl<PatrolWorkOrderMapper, PatrolWorkOrder> implements PatrolWorkOrderService {

    /**
     * 巡检工单mapper
     */
    @Resource
    PatrolWorkOrderMapper patrolWorkOrderMapper;

    /**
     * 基础模块fegin
     */
    @Resource
    FeignService feignService;

    /**
     * 巡检工单-巡检项目service
     */
    @Resource
    PatrolWorkOrderProjectService patrolWorkOrderProjectService;

    /**
     * 巡检工单-巡检项目mapper
     */
    @Resource
    PatrolWorkOrderProjectMapper patrolWorkOrderProjectMapper;

    /**
     * 生产模块fegin
     */
    @Resource
    FeignProductionService feignProductionService;

    /**
     * 巡检项目mapper
     */
    @Resource
    PatrolItemMapper patrolItemMapper;

    /**
     * 巡检工单列表
     *
     * @param patrolWorkOrderVo
     * @return
     */
    @Override
    @DataScope(deptAlias = "a")
    public List<PatrolWorkOrderDto> getList(PatrolWorkOrderVo patrolWorkOrderVo) {

        List<PatrolWorkOrderDto> list = patrolWorkOrderMapper.getList(patrolWorkOrderVo);
        for (PatrolWorkOrderDto entity : list) {
            if (entity.getPatrolStartTime() != null && entity.getPatrolEndTime() != null) {
                entity.setMaintenanceWorkHour(TimeUtils.getDifferHour(entity.getPatrolStartTime(), entity.getPatrolEndTime()));
            }
        }
        return list;
    }

    /**
     * 新增
     *
     * @param patrolWorkOrderVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean add(PatrolWorkOrderVo patrolWorkOrderVo) throws Exception {
        PatrolWorkOrder patrolWorkOrder = new PatrolWorkOrder();
        String authorityCoding = feignService.getAuthorityCoding("device:inspection:workorder:index");
        if (authorityCoding == null) {
            throw new GlobalException("该单据未进行配置，无法生成单据编码");
        }
        patrolWorkOrder.setPatrolNumber(authorityCoding)
                .setCreateBy(SecurityUtils.getUsername())
                .setCreateTime(new Date())
                .setDeptId(SecurityUtils.getDeptId())
                .setStatus(1)
                .setGenerationMode(1)
                .setPatrolItemIdStr(patrolWorkOrderVo.getPatrolItemIdStr())
                .setDeviceId(patrolWorkOrderVo.getDeviceId());
        return save(patrolWorkOrder);
    }

    /**
     * 新增（定时任务调用）
     *
     * @param patrolWorkOrderVo
     * @return
     */
    @Override
    public boolean addScheduling(PatrolWorkOrderVo patrolWorkOrderVo) throws Exception {
        List<String> deviceList = Arrays.asList(patrolWorkOrderVo.getDeviceIds().split(","));
        List<PatrolWorkOrder> patrolWorkOrderList = new ArrayList<>();
        for (String entity : deviceList) {
            PatrolWorkOrder patrolWorkOrder = new PatrolWorkOrder();
            String authorityCoding = feignService.getAuthorityCoding("device:inspection:workorder:index");
            if (authorityCoding == null) {
                throw new GlobalException("该单据未进行配置，无法生成单据编码");
            }
            patrolWorkOrder.setPatrolNumber(authorityCoding)
                    .setSubordinatePlan(patrolWorkOrderVo.getSubordinatePlan())
                    .setCreateBy(SecurityUtils.getUsername())
                    .setCreateTime(new Date())
                    .setDeptId(SecurityUtils.getDeptId())
                    .setStatus(1)
                    .setGenerationMode(2)
                    .setPatrolItemIdStr(patrolWorkOrderVo.getPatrolItemIdStr())
                    .setDeviceId(Long.parseLong(entity));
            patrolWorkOrderList.add(patrolWorkOrder);
        }
        return saveBatch(patrolWorkOrderList);
    }

    /**
     * 巡检工单新增(当日触发调用)
     * @param patrolWorkOrderVo
     * @return
     * @throws Exception
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean addToday(PatrolWorkOrderVo patrolWorkOrderVo) throws Exception {
        List<String> deviceIdList = Arrays.asList(patrolWorkOrderVo.getDeviceIds().split(","));
        List<PatrolWorkOrder> inspectionWorkOrderList = new ArrayList<>();
        for (String entity : deviceIdList) {
            PatrolWorkOrder patrolWorkOrder = new PatrolWorkOrder();
            patrolWorkOrder.setPatrolNumber(feignService.splitList("BYGD"))
                    .setCreateBy(SecurityUtils.getUsername())
                    .setCreateTime(new Date())
                    .setDeptId(SecurityUtils.getDeptId())
                    .setSubordinatePlan(patrolWorkOrderVo.getSubordinatePlan())
                    .setStatus(1)
                    .setGenerationMode(2)
                    .setPatrolItemIdStr(patrolWorkOrderVo.getPatrolItemIdStr())
                    .setDeviceId(Long.parseLong(entity));
            inspectionWorkOrderList.add(patrolWorkOrder);
        }
        return saveBatch(inspectionWorkOrderList);
    }

    /**
     * 派工
     *
     * @param patrolWorkOrderVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean dispatch(PatrolWorkOrderVo patrolWorkOrderVo) {
        PatrolWorkOrder patrolWorkOrder = getById(patrolWorkOrderVo.getId());
        List<String> ids = Arrays.asList(patrolWorkOrderVo.getPatrolPeopleIdStr().split(","));
        patrolWorkOrder.setGroupCode(patrolWorkOrderVo.getGroupCode())
                .setPatrolPeopleIdStr(patrolWorkOrderVo.getPatrolPeopleIdStr())
                .setStatus(2)
                .setPatrolNumberPeople(ids.size());
        return updateById(patrolWorkOrder);
    }

    /**
     * 执行巡检
     *
     * @param patrolWorkOrderVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean execute(PatrolWorkOrderVo patrolWorkOrderVo) {
        PatrolWorkOrder patrolWorkOrder = getById(patrolWorkOrderVo.getId());
        //只有被派工的对应人员才能进行执行操作
        Long userId = SecurityUtils.getUserId();
        List<String> peopleIdList = Arrays.asList(patrolWorkOrder.getPatrolPeopleIdStr().split(","));

        boolean contains = peopleIdList.contains(String.valueOf(userId));
        //获取班组组长id
        String groupCode = patrolWorkOrder.getGroupCode();
        AjaxResult dataByGroupCode = feignProductionService.getDataByGroupCode(groupCode);
        GroupDataDto data = JSON.parseObject(JSON.toJSONString(dataByGroupCode.get("data")), GroupDataDto.class);
        long groupMonitor = data.getGroupMonitor();
        if (!contains && userId != groupMonitor) {
            throw new GlobalException("当前登陆人员不属于该单据的班组组长或保养人员");
        }
        patrolWorkOrder.setPatrolStartTime(patrolWorkOrderVo.getPatrolStartTime())
                .setPatrolEndTime(patrolWorkOrderVo.getPatrolEndTime())
                .setSparePartsIdStr(patrolWorkOrderVo.getSparePartsIdStr())
                .setStatus(3);
        boolean b = updateById(patrolWorkOrder);
        if (b) {
            List<PatrolWorkOrderProjectVo> patrolWorkOrderProjectList = patrolWorkOrderVo.getPatrolWorkOrderProjectVoList();
            List<PatrolWorkOrderProject> result = new ArrayList<>();
            for (PatrolWorkOrderProjectVo entity : patrolWorkOrderProjectList) {
                PatrolWorkOrderProject patrolWorkOrderProject = new PatrolWorkOrderProject();
                patrolWorkOrderProject.setPatrolItemId(entity.getId())
                        .setDecisionResult(entity.getDecisionResultValue())
                        .setResult(entity.getResult())
                        .setRemark(entity.getRemark())
                        .setPatrolWorkOrderId(patrolWorkOrder.getId());
                result.add(patrolWorkOrderProject);
            }
            patrolWorkOrderProjectService.saveBatch(result);
        }
        return b;
    }

    /**
     * 提交审核
     *
     * @param id
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean audit(Long id) {
        PatrolWorkOrder patrolWorkOrder = getById(id);
        patrolWorkOrder.setStatus(4);

        //新增审核代办
        SysWorkbenchAuditAgentVo sysWorkbenchAuditAgentVo = new SysWorkbenchAuditAgentVo();

        sysWorkbenchAuditAgentVo.setDocConfig("device:inspection:workorder:examine");
        sysWorkbenchAuditAgentVo.setReceiptName("巡检工单");
        sysWorkbenchAuditAgentVo.setReceiptNumber(patrolWorkOrder.getPatrolNumber());//
        sysWorkbenchAuditAgentVo.setStatus(1);//待审核
        sysWorkbenchAuditAgentVo.setReceiptContent("有单据待审核,请及时审核");

        feignService.insertAuditAgent(sysWorkbenchAuditAgentVo);

        return updateById(patrolWorkOrder);
    }

    /**
     * 撤销审核
     *
     * @param id
     * @return
     */
    @Override
    public boolean revocation(Long id) {
        PatrolWorkOrder patrolWorkOrder = getById(id);
        patrolWorkOrder.setStatus(3);

        feignService.deleteDoc(patrolWorkOrder.getPatrolNumber(),"巡检工单");

        return updateById(patrolWorkOrder);
    }

    /**
     * 单据审核
     *
     * @param auditVo
     * @return
     */
    @Override
    public boolean documentAudit(AuditVo auditVo) {
        PatrolWorkOrder patrolWorkOrder = getById(auditVo.getId());
        if (patrolWorkOrder.getStatus() == 4 || patrolWorkOrder.getStatus() == 6) {
            String perms = "device:inspection:workorder:examine";
            //获取菜单id
            int isAdopt = auditVo.getAuditResult();
            String auditDoc = patrolWorkOrder.getPatrolNumber();
            String auditRemarks = auditVo.getAuditOpinion();
            Long userId = SecurityUtils.getUserId();
            AjaxResult sequence = feignService.getSequenceTwo(perms, 11, isAdopt, auditRemarks, auditDoc, userId);
            Integer data = JSON.parseObject(JSON.toJSONString(sequence.get("data")), Integer.class);
            if (data == null) {
                throw new GlobalException("未对该审核进行配置");
            }
            //1:通过，2：审核中，3：没权限 4:该人已经审核过
            if (auditVo.getAuditResult() == 1) {
                if (data == 1) {
                    patrolWorkOrder.setStatus(7);

                    feignService.updateStatus(3,patrolWorkOrder.getPatrolNumber(),"巡检工单");

                    return updateById(patrolWorkOrder);
                } else if (data == 2) {
                    patrolWorkOrder.setStatus(6);
                    return updateById(patrolWorkOrder);
                } else if (data == 3) {
                    throw new GlobalException("没有审核权限");
                } else {
                    throw new GlobalException("该用户已经审核过");
                }
            } else {
                if (data == 1 || data == 2) {
                    patrolWorkOrder.setStatus(5);

                    //新增审核代办
                    SysWorkbenchAuditAgentVo sysWorkbenchAuditAgentVo = new SysWorkbenchAuditAgentVo();

                    sysWorkbenchAuditAgentVo.setDocConfig("device:inspection:workorder:examine");
                    sysWorkbenchAuditAgentVo.setReceiptName("巡检工单");
                    sysWorkbenchAuditAgentVo.setReceiptNumber(patrolWorkOrder.getPatrolNumber());//
                    sysWorkbenchAuditAgentVo.setStatus(2);//待处理
                    sysWorkbenchAuditAgentVo.setReceiptContent("有单据未通过,请及时查看");

                    sysWorkbenchAuditAgentVo.setPassFlag("1");
                    sysWorkbenchAuditAgentVo.setCreateName(patrolWorkOrder.getCreateBy());

                    feignService.insertAuditAgent(sysWorkbenchAuditAgentVo);

                    return updateById(patrolWorkOrder);
                } else if (data == 3) {
                    throw new GlobalException("没有审核权限");
                } else {
                    throw new GlobalException("该用户已经审核过");
                }
            }
        } else {
            throw new GlobalException("只能对待审核和审核中的数据进行处理");
        }
    }

    /**
     * 修改
     *
     * @param patrolWorkOrderVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updatePatrolWorkOrder(PatrolWorkOrderVo patrolWorkOrderVo) {
        PatrolWorkOrder patrolWorkOrder = getById(patrolWorkOrderVo.getId());
        if (patrolWorkOrder.getStatus() == 5) {
            patrolWorkOrder.setDeviceId(patrolWorkOrderVo.getDeviceId())
                    .setPatrolPeopleIdStr(patrolWorkOrderVo.getPatrolPeopleIdStr())
                    .setPatrolItemIdStr(patrolWorkOrderVo.getPatrolItemIdStr())
                    .setGroupCode(patrolWorkOrderVo.getGroupCode())
                    .setPatrolStartTime(patrolWorkOrderVo.getPatrolStartTime())
                    .setPatrolEndTime(patrolWorkOrderVo.getPatrolEndTime());
            //调用审核
            SysAuditHistoryVo sysAuditHistoryVo = new SysAuditHistoryVo();
            String perms = "device:inspection:workorder:examine";
            String auditDoc = patrolWorkOrder.getPatrolNumber();
            sysAuditHistoryVo.setAuditDoc(auditDoc);
            sysAuditHistoryVo.setPerms(perms);
            AjaxResult history = feignService.editHistory(sysAuditHistoryVo);
            String data = JSON.parseObject(JSON.toJSONString(history.get("msg")), String.class);
            if ("操作成功".equals(data)) {
                patrolWorkOrder.setStatus(3);

                //修改审核代办状态为已处理
                feignService.updateStatus(3,patrolWorkOrder.getPatrolNumber(),"巡检工单");//
            } else {
                return false;
            }
            updateById(patrolWorkOrder);
            //获取该保养工单下之前的保养工单-保养项目数据并删除
            List<PatrolWorkOrderProject> patrolWorkOrderProjectList = patrolWorkOrderProjectMapper.selectList(new QueryWrapper<PatrolWorkOrderProject>().lambda().eq(PatrolWorkOrderProject::getPatrolWorkOrderId, patrolWorkOrder.getId()));
            if (patrolWorkOrderProjectList.size() > 0) {
                patrolWorkOrderProjectMapper.deleteBatchIds(patrolWorkOrderProjectList);
            }
            List<PatrolWorkOrderProjectVo> patrolWorkOrderProjectVoList = patrolWorkOrderVo.getPatrolWorkOrderProjectVoList();
            List<PatrolWorkOrderProject> result = new ArrayList<>();
            for (PatrolWorkOrderProjectVo entity : patrolWorkOrderProjectVoList) {
                PatrolWorkOrderProject patrolWorkOrderProject = new PatrolWorkOrderProject();
                patrolWorkOrderProject.setPatrolItemId(entity.getId())
                        .setDecisionResult(entity.getDecisionResultValue())
                        .setResult(entity.getResult())
                        .setRemark(entity.getRemark())
                        .setPatrolWorkOrderId(patrolWorkOrder.getId());
                result.add(patrolWorkOrderProject);
            }
            return patrolWorkOrderProjectService.saveBatch(result);
        } else {
            throw new GlobalException("只能修改未通过的单据");
        }

    }

    /**
     * 查看
     *
     * @param id
     * @return
     */
    @Override
    public PatrolWorkOrderDto getView(Long id) {
        PatrolWorkOrderDto patrolWorkOrderDto = patrolWorkOrderMapper.getDataById(id);
        //通过线别编码获取线别名称
        String lineCode = patrolWorkOrderDto.getInstallationLocation();
        AjaxResult modelingLineInfo = feignService.getModelingLineInfo(lineCode);
        SysLineDto sysLineDto = JSON.parseObject(JSON.toJSONString(modelingLineInfo.get("data")), SysLineDto.class);
        patrolWorkOrderDto.setLineName(sysLineDto.getLineName());
        //获取保养级别字典
        List<SysDictData> levelArray = DictUtils.getDictCache("maintenance_project_level");
        Map<String, String> levelMap = levelArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
        //班组数据
        String groupCode = patrolWorkOrderDto.getGroupCode();
        if (groupCode != null) {
            AjaxResult dataByGroupCode = feignProductionService.getDataByGroupCode(groupCode);
            GroupDataDto data = JSON.parseObject(JSON.toJSONString(dataByGroupCode.get("data")), GroupDataDto.class);
            patrolWorkOrderDto.setGroupName(data.getGroupName());
            patrolWorkOrderDto.setGroupMonitorName(data.getGroupMonitorName());
            patrolWorkOrderDto.setGroupMonitor(data.getGroupMonitor());

            //通过组员id获取组员名称
            String ids = patrolWorkOrderDto.getPatrolPeopleIdStr();

            AjaxResult userNameByIds = feignService.getUserNameByIds(ids);
            List<SysUser> data1 = JSON.parseArray(JSON.toJSONString(userNameByIds.get("data")), SysUser.class);
            List<GroupMemberDto> groupMemberList = new ArrayList<>();
            for (SysUser entity : data1) {
                GroupMemberDto groupMemberDto = new GroupMemberDto();
                groupMemberDto.setId(entity.getUserId());
                groupMemberDto.setName(entity.getUserName());
                groupMemberList.add(groupMemberDto);
            }

            patrolWorkOrderDto.setGroupMemberList(groupMemberList);
        }

        //获取点检工单-点检项目数据
        List<PatrolWorkOrderProject> patrolWorkOrderProjectList = patrolWorkOrderProjectMapper.selectList(new QueryWrapper<PatrolWorkOrderProject>().lambda().eq(PatrolWorkOrderProject::getPatrolWorkOrderId, patrolWorkOrderDto.getId()));
        if (patrolWorkOrderProjectList.size() > 0) {
            //根据id获取巡检项目列表
            List<String> patrolItemIdStr = Arrays.asList(patrolWorkOrderDto.getPatrolItemIdStr().split(","));
            List<PatrolItemDto> result = new ArrayList<>();
            List<PatrolItem> patrolItems = patrolItemMapper.selectList(new QueryWrapper<PatrolItem>().lambda().in(PatrolItem::getId, patrolItemIdStr));
            for (PatrolWorkOrderProject entity : patrolWorkOrderProjectList) {
                for (PatrolItem patrolItem : patrolItems) {
                    if (entity.getPatrolItemId() == patrolItem.getId()) {
                        PatrolItemDto patrolItemDto = new PatrolItemDto();

                        patrolItemDto.setId(patrolItem.getId());
                        patrolItemDto.setPatrolItemCode(patrolItem.getPatrolItemCode());
                        patrolItemDto.setPatrolItemContent(patrolItem.getPatrolItemContent());
                        patrolItemDto.setPatrolItemName(patrolItem.getPatrolItemName());
                        patrolItemDto.setInspectionStandard(patrolItem.getInspectionStandard());
                        patrolItemDto.setWorkingHour(patrolItem.getWorkingHour());
                        patrolItemDto.setInspectionType(patrolItem.getInspectionType());
                        patrolItemDto.setDecisionResult(patrolItem.getDecisionResult());
                        patrolItemDto.setDecisionResultValue(entity.getDecisionResult());
                        patrolItemDto.setResult(entity.getResult());
                        patrolItemDto.setRemark(entity.getRemark());

                        result.add(patrolItemDto);
                    }
                }
            }
            patrolWorkOrderDto.setPatrolOrderProjectList(result);
        } else {
            List<String> patrolItemIds = Arrays.asList(patrolWorkOrderDto.getPatrolItemIdStr().split(","));
            List<PatrolItem> allList = patrolItemMapper.getAllList(patrolItemIds);
//            List<PatrolItem> patrolItemList = patrolItemMapper.selectList(new QueryWrapper<PatrolItem>().lambda().in(PatrolItem::getId, patrolWorkOrderDto.getPatrolItemIdStr()));
            patrolWorkOrderDto.setPatrolItemList(allList);
        }

        return patrolWorkOrderDto;
    }

    /**
     * 删除
     *
     * @param id
     * @return
     */
    @Override
    public boolean deleteWorkOrder(Long id) {
        PatrolWorkOrder byId = getById(id);
        if (byId.getStatus() == 1) {
            feignService.deleteDoc(byId.getPatrolNumber(),"巡检工单");
            return removeById(id);
        } else {
            throw new GlobalException("只能删除待派工的单据");
        }
    }
}
